package edu.um.automata;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

import edu.um.automata.exception.StateNotFoundException;
import edu.um.automata.exception.TransitionNotFoundException;
import edu.um.io.Console;
import edu.um.token.TokenKind;

public class StackAutomata {

  private final Stack<StackSymbol> stack = new Stack<StackSymbol>();

  private String actualState = "0";

  private static Set<String> acceptStates = new HashSet<String>();

  private static TransitionTable table;

  static {
    acceptStates.addAll(Arrays.asList("-1", "9001"));
    table = new TransitionTable();
    try {
      table.addTransition("-1", new Transition(TokenKind.VAR), "1");
      table.addTransition("0", new Transition(TokenKind.VAR), "1");
      table.addTransition("1", new Transition(TokenKind.ID), "2");
      table.addTransition("1", new Transition(TokenKind.ID, StackSymbol.REGISTRO, StackSymbol.REGISTRO), "2");
      table.addTransition("2", new Transition(TokenKind.DEFINE_TIPO_DATO), "3");
      table.addTransition("2", new Transition(TokenKind.DEFINE_TIPO_DATO, StackSymbol.REGISTRO, StackSymbol.REGISTRO), "3");
      table.addTransition("3", new Transition(TokenKind.TIPO_WORD), "4");
      table.addTransition("3", new Transition(TokenKind.TIPO_BYTE), "4");
      table.addTransition("3", new Transition(TokenKind.TIPO_STRING_BLANCO), "4");
      table.addTransition("3", new Transition(TokenKind.TIPO_STRING_SUBRAYADO), "4");
      table.addTransition("3", new Transition(TokenKind.TIPO_WORD, StackSymbol.REGISTRO, StackSymbol.REGISTRO), "4");
      table.addTransition("3", new Transition(TokenKind.TIPO_BYTE, StackSymbol.REGISTRO, StackSymbol.REGISTRO), "4");
      table.addTransition("3", new Transition(TokenKind.TIPO_STRING_BLANCO, StackSymbol.REGISTRO, StackSymbol.REGISTRO), "4");
      table.addTransition("3", new Transition(TokenKind.TIPO_STRING_SUBRAYADO, StackSymbol.REGISTRO, StackSymbol.REGISTRO), "4");
      table.addTransition("3", new Transition(TokenKind.TIPO_ARRAY), "6");
      table.addTransition("3", new Transition(TokenKind.TIPO_RECORD, null, StackSymbol.REGISTRO), "1");
      table.addTransition("4", new Transition(TokenKind.FIN_SENTENCIA), "0");
      table.addTransition("4", new Transition(TokenKind.FIN_SENTENCIA, StackSymbol.REGISTRO, StackSymbol.REGISTRO), "5");
      table.addTransition("5", new Transition(TokenKind.END, StackSymbol.REGISTRO), "4");
      table.addTransition("5", new Transition(TokenKind.ID, StackSymbol.REGISTRO, StackSymbol.REGISTRO), "2");
      table.addTransition("6", new Transition(TokenKind.ABRE_CORCHETE), "7");
      table.addTransition("7", new Transition(TokenKind.CONST_BYTE), "8");
      table.addTransition("7", new Transition(TokenKind.CONST_WORD), "8");
      table.addTransition("8", new Transition(TokenKind.INTERVALO), "9");
      table.addTransition("9", new Transition(TokenKind.CONST_BYTE), "10");
      table.addTransition("9", new Transition(TokenKind.CONST_WORD), "10");
      table.addTransition("10", new Transition(TokenKind.COMA), "7");
      table.addTransition("10", new Transition(TokenKind.CIERRA_CORCHETE), "11");
      table.addTransition("11", new Transition(TokenKind.OF), "12");
      table.addTransition("12", new Transition(TokenKind.TIPO_BYTE), "4");
      table.addTransition("12", new Transition(TokenKind.TIPO_WORD), "4");
      table.addTransition("12", new Transition(TokenKind.TIPO_STRING_BLANCO), "4");
      table.addTransition("12", new Transition(TokenKind.TIPO_STRING_SUBRAYADO), "4");

      //Begin
      table.addTransition("-1", new Transition(TokenKind.BEGIN), "30");
      table.addTransition("0", new Transition(TokenKind.BEGIN), "30");

      table.addTransition(30, 400, TokenKind.WRITELN, null, StackSymbol.WRITELN);
      table.addTransition(30, 400, TokenKind.WRITELN, StackSymbol.IF_SENTENCE, StackSymbol.WRITELN);

      table.addTransition(30, 500, TokenKind.READLN, null, StackSymbol.READLN);
      table.addTransition(30, 500, TokenKind.READLN, StackSymbol.IF_SENTENCE, StackSymbol.READLN);

      table.addTransition(30, 520, TokenKind.ID, null, StackSymbol.ID_ASIGNACION);
      table.addTransition(30, 520, TokenKind.ID, StackSymbol.IF_SENTENCE, StackSymbol.ID_ASIGNACION);

      table.addTransition(30, 410, TokenKind.IF, null, StackSymbol.IF_EXPRESION);

      //400
      table.addTransition(400, 410, TokenKind.ABRE_PARENTESIS, StackSymbol.WRITELN, StackSymbol.WRITELN, StackSymbol.PARENTESIS);

      //410
      table.addTransition(410, 410, TokenKind.ABRE_PARENTESIS, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(410, 410, TokenKind.ABRE_PARENTESIS, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION, StackSymbol.PARENTESIS);
      table.addTransition(410, 410, TokenKind.ABRE_PARENTESIS, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.PARENTESIS);
      table.addTransition(410, 410, TokenKind.ABRE_PARENTESIS, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION, StackSymbol.PARENTESIS);

      table.addTransition(410, 450, TokenKind.STRING_BLANCO, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(410, 450, TokenKind.STRING_SUBRAYADO, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(410, 450, TokenKind.STRING_BLANCO, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(410, 450, TokenKind.STRING_SUBRAYADO, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(410, 450, TokenKind.STRING_BLANCO, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(410, 450, TokenKind.STRING_SUBRAYADO, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(410, 450, TokenKind.STRING_BLANCO, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION);
      table.addTransition(410, 450, TokenKind.STRING_SUBRAYADO, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION);

      table.addTransition(410, 460, TokenKind.OPERADOR_UNARIO, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(410, 460, TokenKind.OPERADOR_UNARIO);

      table.addTransition(410, 440, TokenKind.CONST_WORD, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(410, 440, TokenKind.CONST_BYTE, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(410, 440, TokenKind.CONST_WORD, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(410, 440, TokenKind.CONST_BYTE, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(410, 440, TokenKind.CONST_WORD, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(410, 440, TokenKind.CONST_BYTE, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(410, 440, TokenKind.CONST_WORD, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION);
      table.addTransition(410, 440, TokenKind.CONST_BYTE, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION);

      table.addTransition(410, 420, TokenKind.ID, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(410, 420, TokenKind.ID, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(410, 420, TokenKind.ID, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(410, 420, TokenKind.ID, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION);

      // 420 -----------
      table.addTransition(420, 430, TokenKind.PUNTO, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(420, 430, TokenKind.PUNTO, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION);
      table.addTransition(420, 430, TokenKind.PUNTO, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(420, 430, TokenKind.PUNTO, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
//      table.addTransition(420, 430, TokenKind.PUNTO, StackSymbol.CORCHETE, StackSymbol.CORCHETE);

      table.addTransition(420, 440, TokenKind.CIERRA_CORCHETE, StackSymbol.CORCHETE);
      table.addTransition(420, 440, TokenKind.CIERRA_PARENTESIS, StackSymbol.PARENTESIS);

      table.addTransition(420, 30, TokenKind.FIN_SENTENCIA, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(420, 410, TokenKind.COMPARADOR, StackSymbol.IF_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(420, 30, TokenKind.THEN, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_SENTENCE);
      table.addTransition(420, 30, TokenKind.FIN_SENTENCIA, StackSymbol.WRITELN);

      table.addTransition(420, 460, TokenKind.COMA, StackSymbol.CORCHETE, StackSymbol.CORCHETE);
      table.addTransition(420, 460, TokenKind.OPERADOR, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(420, 460, TokenKind.OPERADOR, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION);
      table.addTransition(420, 460, TokenKind.OPERADOR, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(420, 460, TokenKind.OPERADOR, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(420, 460, TokenKind.OPERADOR, StackSymbol.CORCHETE, StackSymbol.CORCHETE);
      table.addTransition(420, 460, TokenKind.ABRE_CORCHETE, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION, StackSymbol.CORCHETE);
      table.addTransition(420, 460, TokenKind.ABRE_CORCHETE, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION, StackSymbol.CORCHETE);
      table.addTransition(420, 460, TokenKind.ABRE_CORCHETE, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.CORCHETE);
      table.addTransition(420, 460, TokenKind.ABRE_CORCHETE, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS, StackSymbol.CORCHETE);
//      table.addTransition(420, 460, TokenKind.ABRE_CORCHETE, StackSymbol.CORCHETE, StackSymbol.CORCHETE, StackSymbol.CORCHETE);


      //430 -----------
      table.addTransition(430, 440, TokenKind.ID, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(430, 440, TokenKind.ID, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION);
      table.addTransition(430, 440, TokenKind.ID, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(430, 440, TokenKind.ID, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(430, 440, TokenKind.ID, StackSymbol.CORCHETE, StackSymbol.CORCHETE);

      //440
      table.addTransition(440, 440, TokenKind.CIERRA_PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(440, 440, TokenKind.CIERRA_CORCHETE, StackSymbol.CORCHETE);

      table.addTransition(440, 460, TokenKind.COMA, StackSymbol.CORCHETE, StackSymbol.CORCHETE);
      table.addTransition(440, 460, TokenKind.OPERADOR, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(440, 460, TokenKind.OPERADOR, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION);
      table.addTransition(440, 460, TokenKind.OPERADOR, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(440, 460, TokenKind.OPERADOR, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(440, 460, TokenKind.OPERADOR, StackSymbol.CORCHETE, StackSymbol.CORCHETE);

      table.addTransition(440, 30, TokenKind.FIN_SENTENCIA, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(440, 410, TokenKind.COMPARADOR, StackSymbol.IF_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(440, 30, TokenKind.THEN, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_SENTENCE);
      table.addTransition(440, 30, TokenKind.FIN_SENTENCIA, StackSymbol.WRITELN);

      //450
      table.addTransition(450, 450, TokenKind.CIERRA_PARENTESIS, StackSymbol.PARENTESIS);

      table.addTransition(450, 30, TokenKind.FIN_SENTENCIA, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(450, 410, TokenKind.COMPARADOR, StackSymbol.IF_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(450, 30, TokenKind.THEN, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_SENTENCE);
      table.addTransition(450, 30, TokenKind.FIN_SENTENCIA, StackSymbol.WRITELN);

      //460
      table.addTransition(460, 420, TokenKind.ID, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(460, 420, TokenKind.ID, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION);
      table.addTransition(460, 420, TokenKind.ID, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(460, 420, TokenKind.ID, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(460, 420, TokenKind.ID, StackSymbol.CORCHETE, StackSymbol.CORCHETE);

      table.addTransition(460, 440, TokenKind.CONST_WORD, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(460, 440, TokenKind.CONST_WORD, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION);
      table.addTransition(460, 440, TokenKind.CONST_WORD, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(460, 440, TokenKind.CONST_WORD, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(460, 440, TokenKind.CONST_WORD, StackSymbol.CORCHETE, StackSymbol.CORCHETE);
      table.addTransition(460, 440, TokenKind.CONST_BYTE, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(460, 440, TokenKind.CONST_BYTE, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);
      table.addTransition(460, 440, TokenKind.CONST_BYTE, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION);
      table.addTransition(460, 440, TokenKind.CONST_BYTE, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(460, 440, TokenKind.CONST_BYTE, StackSymbol.CORCHETE, StackSymbol.CORCHETE);

      table.addTransition(460, 460, TokenKind.ABRE_PARENTESIS, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION, StackSymbol.PARENTESIS);
      table.addTransition(460, 460, TokenKind.ABRE_PARENTESIS, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION, StackSymbol.PARENTESIS);
      table.addTransition(460, 460, TokenKind.ABRE_PARENTESIS, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.PARENTESIS);
      table.addTransition(460, 460, TokenKind.ABRE_PARENTESIS, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(460, 460, TokenKind.ABRE_PARENTESIS, StackSymbol.CORCHETE, StackSymbol.CORCHETE, StackSymbol.PARENTESIS);
      table.addTransition(460, 460, TokenKind.OPERADOR_UNARIO, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(460, 460, TokenKind.OPERADOR_UNARIO, StackSymbol.CORCHETE, StackSymbol.CORCHETE);
      table.addTransition(460, 460, TokenKind.OPERADOR_UNARIO, StackSymbol.VALOR_ASIGNACION, StackSymbol.VALOR_ASIGNACION);
      table.addTransition(460, 460, TokenKind.OPERADOR_UNARIO, StackSymbol.IF_EXPRESION, StackSymbol.IF_EXPRESION);
      table.addTransition(460, 460, TokenKind.OPERADOR_UNARIO, StackSymbol.IF_COMPARE_TO_EXPRESION, StackSymbol.IF_COMPARE_TO_EXPRESION);

      // READLN
      //500
      table.addTransition(500, 510, TokenKind.ABRE_PARENTESIS, StackSymbol.READLN, StackSymbol.READLN, StackSymbol.PARENTESIS);

      //510
      table.addTransition(510, 520, TokenKind.ID, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(510, 510, TokenKind.ABRE_PARENTESIS, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);

      //520
      table.addTransition(520, 520, TokenKind.CIERRA_PARENTESIS, StackSymbol.PARENTESIS);

      table.addTransition(520, 30, TokenKind.FIN_SENTENCIA, StackSymbol.READLN);

      table.addTransition(520, 410, TokenKind.ASIGNA_VALOR, StackSymbol.ID_ASIGNACION, StackSymbol.VALOR_ASIGNACION);

      table.addTransition(520, 530, TokenKind.PUNTO, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(520, 530, TokenKind.PUNTO, StackSymbol.ID_ASIGNACION, StackSymbol.ID_ASIGNACION);

      table.addTransition(520, 550, TokenKind.ABRE_CORCHETE, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS, StackSymbol.CORCHETE);
      table.addTransition(520, 550, TokenKind.ABRE_CORCHETE, StackSymbol.ID_ASIGNACION, StackSymbol.ID_ASIGNACION, StackSymbol.CORCHETE);

      //530
      table.addTransition(530, 540, TokenKind.ID, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);

      table.addTransition(530, 540, TokenKind.ID, StackSymbol.ID_ASIGNACION, StackSymbol.ID_ASIGNACION);

      //540
      table.addTransition(540, 540, TokenKind.CIERRA_PARENTESIS, StackSymbol.PARENTESIS);

      table.addTransition(540, 30, TokenKind.FIN_SENTENCIA, StackSymbol.READLN);

      table.addTransition(540, 410, TokenKind.ASIGNA_VALOR, StackSymbol.ID_ASIGNACION, StackSymbol.VALOR_ASIGNACION);

      //550
      table.addTransition(550, 550, TokenKind.ABRE_PARENTESIS, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(550, 550, TokenKind.ABRE_PARENTESIS, StackSymbol.CORCHETE, StackSymbol.CORCHETE, StackSymbol.PARENTESIS);
      table.addTransition(550, 550, TokenKind.OPERADOR_UNARIO, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(550, 550, TokenKind.OPERADOR_UNARIO, StackSymbol.CORCHETE, StackSymbol.CORCHETE);

      table.addTransition(550, 560, TokenKind.ID, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(550, 560, TokenKind.ID, StackSymbol.CORCHETE, StackSymbol.CORCHETE);

      table.addTransition(550, 580, TokenKind.CONST_WORD, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(550, 580, TokenKind.CONST_WORD, StackSymbol.CORCHETE, StackSymbol.CORCHETE);
      table.addTransition(550, 580, TokenKind.CONST_BYTE, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(550, 580, TokenKind.CONST_BYTE, StackSymbol.CORCHETE, StackSymbol.CORCHETE);

      //560
      table.addTransition(560, 550, TokenKind.OPERADOR, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(560, 550, TokenKind.OPERADOR, StackSymbol.CORCHETE, StackSymbol.CORCHETE);
      table.addTransition(560, 550, TokenKind.ABRE_CORCHETE, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS, StackSymbol.CORCHETE);
//      table.addTransition(560, 550, TokenKind.ABRE_CORCHETE, StackSymbol.CORCHETE, StackSymbol.CORCHETE, StackSymbol.CORCHETE);
      table.addTransition(560, 550, TokenKind.COMA, StackSymbol.CORCHETE, StackSymbol.CORCHETE);

      table.addTransition(560, 570, TokenKind.PUNTO, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
//      table.addTransition(560, 570, TokenKind.PUNTO, StackSymbol.CORCHETE, StackSymbol.CORCHETE);

      table.addTransition(560, 580, TokenKind.CIERRA_PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(560, 580, TokenKind.CIERRA_CORCHETE, StackSymbol.CORCHETE);

      //570
      table.addTransition(570, 580, TokenKind.ID, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(570, 580, TokenKind.ID, StackSymbol.CORCHETE, StackSymbol.CORCHETE);

      //580
      table.addTransition(580, 550, TokenKind.OPERADOR, StackSymbol.PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(580, 550, TokenKind.OPERADOR, StackSymbol.CORCHETE, StackSymbol.CORCHETE);
      table.addTransition(580, 550, TokenKind.COMA, StackSymbol.CORCHETE, StackSymbol.CORCHETE);

      table.addTransition(580, 580, TokenKind.CIERRA_PARENTESIS, StackSymbol.PARENTESIS);
      table.addTransition(580, 580, TokenKind.CIERRA_CORCHETE, StackSymbol.CORCHETE);

      table.addTransition(580, 30, TokenKind.FIN_SENTENCIA, StackSymbol.READLN);

      table.addTransition(580, 410, TokenKind.ASIGNA_VALOR, StackSymbol.ID_ASIGNACION, StackSymbol.VALOR_ASIGNACION);

      //TEMP
      table.addTransition(3000, 30, TokenKind.FIN_SENTENCIA);


      // END
      table.addTransition(30, 9000, TokenKind.END);
      table.addTransition(9000, 9001, TokenKind.PUNTO);


    } catch(Exception e) {
      e.printStackTrace();
    }
  }

  public void process(TokenKind tokenKind) throws StateNotFoundException,
      TransitionNotFoundException {
    Map<String, Collection<Transition>> file = table.getFile(actualState);
    if (file == null) {
      // Should not happen
      throw new StateNotFoundException(actualState);
    }
    StackSymbol stackSymbol = null;
    if (!stack.isEmpty()) {
      stackSymbol = stack.pop();
    }
    for (String state : file.keySet()) {
      Collection<Transition> transitions = file.get(state);
      for (Transition transition : transitions) {
        if (transition.getTokenKind() == tokenKind
            && transition.getStackSymbolReceived() == stackSymbol) {
          actualState = state;
          Console.debug("Actual State: " + state);
          if (transition.getStackSymbolPut1() != null) {
            stack.push(transition.getStackSymbolPut1());
          }
          if (transition.getStackSymbolPut2() != null) {
            stack.push(transition.getStackSymbolPut2());
          }
          return;
        }
      }

    }
    throw new TransitionNotFoundException(actualState + " - " + tokenKind
        + "::" + stackSymbol);
  }

  public boolean isInAcceptableState() {
    return acceptStates.contains(actualState);
  }
}
